package com.small.nacos.client.config;


import com.small.nacos.api.exception.NacosException;
import com.small.nacos.api.config.ConfigService;
import com.small.nacos.api.config.listener.Listener;
import com.small.nacos.client.config.filter.impl.ConfigResponse;
import com.small.nacos.client.config.http.HttpAgent;
import com.small.nacos.client.config.http.ServerHttpAgent;
import com.small.nacos.client.config.impl.ClientWorker;
import com.small.nacos.client.config.impl.LocalConfigInfoProcessor;
import com.small.nacos.client.utils.GroupUtils;
import com.small.nacos.client.utils.ParamUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Properties;

/**
 * @Author zhoujin
 * @Date 2022/11/18 11:01
 */
public class NacosConfigService implements ConfigService {

    private final static Logger LOGGER = LoggerFactory.getLogger(NacosConfigService.class);

    private String namespace;

    private HttpAgent agent;

    private final ClientWorker worker;

    public NacosConfigService(Properties properties) {
        initNamespace(properties);
        this.agent = new ServerHttpAgent(properties);
        this.worker = new ClientWorker(this.agent, properties);
    }

    private void initNamespace(Properties properties) {
        //获取命名空间
        this.namespace = ParamUtil.parseNamespace(properties);
    }

    @Override
    public String getConfig(String dataId, String group, long timeoutMs) throws NacosException {
        return getConfigInner(namespace, dataId, group, timeoutMs);
    }

    @Override
    public void addListener(String dataId, String group, Listener listener) throws NacosException {
        worker.addTenantListeners(dataId, group, Arrays.asList(listener));
    }


    /**
     * 获取配置
     *
     * @param tenant    public
     * @param dataId    配置文件
     * @param group     分组
     * @param timeoutMs
     * @return
     * @throws NacosException
     */
    private String getConfigInner(String tenant, String dataId, String group, long timeoutMs) throws NacosException {
        //如果没有使用默认group
        group = GroupUtils.blank2defaultGroup(group);

        String agentName = agent.getName();
        ConfigResponse cr = new ConfigResponse();

        cr.setDataId(dataId);
        cr.setTenant(tenant);
        cr.setGroup(group);

        //获取故障转移文件配置
        String content = LocalConfigInfoProcessor.getFailover(agentName, dataId, group, tenant);
        if (content != null) {
            cr.setContent(content);
            return content;
        }
        try {
            //获取配置中心配置
            ConfigResponse response = worker.getServerConfig(dataId, group, tenant, timeoutMs);
            cr.setContent(response.getContent());
            content = cr.getContent();
            return content;
        } catch (NacosException ioe) {
            if (NacosException.NO_RIGHT == ioe.getErrCode()) {
                throw ioe;
            }
            LOGGER.warn("[{}] [get-config] get from server error, dataId={}, group={}, tenant={}, msg={}",
                    agent.getName(), dataId, group, tenant, ioe.toString());
        }

        //获取临时配置文件
        content = LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant);

        cr.setContent(content);
        content = cr.getContent();
        return content;
    }
}